package com.fhb.java.d20250609.泛型;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @author abao
 * @Description TODO
 * @createTime 2025-06-09 17:17:00
 * <p>
 * PECS原则（Producer-Extends, Consumer-Super）
 * 这是Joshua Bloch在《Effective Java》中提出的核心原则：
 * <p>
 * Producer（生产者）：如果参数化类型表示一个生产者（提供数据），使用<? extends T>
 * Consumer（消费者）：如果参数化类型表示一个消费者（接收数据），使用<? super T>
 */
public class 泛型Extends和super测试 {


    public void test_extends() {
        // 只能放入null，但可以安全读取为Number
        List<? extends Number> numbers = new ArrayList<Integer>();

        // 读取安全（所有元素都是Number或其子类）
        Number n = numbers.get(0);
        Double d = (Double) numbers.get(0); // 需类型转换

        // 写入不安全（编译错误）
//        numbers.add(10);      // 错误
//        numbers.add(3.14);    // 错误
        numbers.add(null);    // 唯一允许的写入操作
    }


    public void test_supper() {

        // 可以安全添加Integer及其子类
        List<? super Number> numbers = new ArrayList<Object>();

        // 写入安全
        numbers.add(Integer.valueOf(10));
        numbers.add(Double.valueOf(3.14));

        // 读取不安全（只能作为Object）
        Object obj = numbers.get(0);   // 安全
//        Number num = numbers.get(0);    // 编译错误（类型不安全）
    }


    public void test_copy(){
        List<Integer> integers = Arrays.asList(1, 2, 3);
        List<Number> numbers = new ArrayList<>();

        // 安全拷贝：Integer是Number的子类
        Collections.copy(numbers, integers);
    }




    // Java标准库中的Collections.copy()实现
    public static <T> void copy(
            List<? super T> dest,   // 消费者（写入目标）
            List<? extends T> src   // 生产者（数据来源）
    ) {
        for (int i = 0; i < src.size(); i++) {
            dest.set(i, src.get(i)); // 安全：src生产T，dest消费T
        }
    }

}
